package com.company.cloud.pay.modules.third.service;

import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.company.cloud.pay.modules.alipay.AliPayApi;
import com.company.cloud.pay.modules.alipay.AliPayApiConfig;
import com.company.cloud.pay.modules.alipay.AliPayApiConfigKit;
import com.company.cloud.pay.modules.api.constant.PayTradeType;
import com.company.cloud.pay.modules.api.request.PayOrderCloseRequest;
import com.company.cloud.pay.modules.api.request.PayOrderQueryRequest;
import com.company.cloud.pay.modules.api.request.PayOrderRequest;
import com.company.cloud.pay.modules.cache.model.PayApiConfig;
import com.company.cloud.pay.modules.third.factory.CloudPayApiService;
import com.company.cloud.pay.modules.third.models.ThirdPayResp;
import com.company.cloud.pay.modules.third.models.ThirdQueryOrderResp;
import com.company.cloud.pay.modules.third.models.ThirdUnifiedOrderResp;
import com.company.cloud.pay.modules.third.utils.WxPayStateConvertKit;
import com.company.cloud.pay.modules.wxpay.WxPayApiConfig;

import cn.hutool.core.util.StrUtil;

public class AliCloudPayApiService implements CloudPayApiService {

    /**
     * 支付回调地址
     */
    public static String getNotifyUrl(PayApiConfig payConfig) {
        String path = StrUtil.format("/pay/alipay/{}/payNotify", payConfig.getConfigId());
        return payConfig.getDomain().concat(path);
    }


    private AliPayApiConfig getAliPayApiConfig(PayApiConfig payConfig) {
        String serviceUrl = "https://openapi.alipay.com/gateway.do";

        AliPayApiConfig aliPayApiConfig =
                AliPayApiConfig.builder()
                        .setAppId(payConfig.getAppId())
                        .setServiceUrl(serviceUrl)
                        .setCharset("utf-8")
                        .setSignType("RSA2")
                        .setPrivateKey(payConfig.getAliPrivateKey())
                        .setAliPayPublicKey(payConfig.getAlipayPublicKey()).build();

        return aliPayApiConfig;

    }


    @Override
    public ThirdUnifiedOrderResp unifiedOrder(PayApiConfig payConfig, PayOrderRequest request) {

        ThirdUnifiedOrderResp result = new ThirdUnifiedOrderResp();

        AliPayApiConfig aliPayApiConfig = this.getAliPayApiConfig(payConfig);
        AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
        float f = request.getTotalFee() / 100f;

        PayTradeType ptt = request.getPtt();
        switch (ptt.getTradeType()) {

            case "WEB":
                AlipayTradePagePayModel model = new AlipayTradePagePayModel();
                model.setOutTradeNo(request.getOutTradeNo()); //
                model.setProductCode("FAST_INSTANT_TRADE_PAY");

                model.setTotalAmount(String.valueOf(f));
                model.setSubject(request.getBody());
                model.setGoodsType("1");

                AlipayTradePagePayRequest callReq = new AlipayTradePagePayRequest();
                callReq.setBizModel(model);
                callReq.setNotifyUrl(this.getNotifyUrl(payConfig));
                callReq.setReturnUrl(request.getReturnUrl());

                try {
                    result.addReq(JSON.toJSONString(callReq));
                    String form = AliPayApi.pageExecute(callReq).getBody();
                    result.addResp(form);
                    Map<String, String> biz = new HashMap<String, String>();
                    biz.put("html", form);
                    result.setBiz(biz);
                    System.out.println(JSON.toJSONString(result));
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                } finally {
                    AliPayApiConfigKit.removeThreadLocalAppId();
                }

                return result;

            case "APP" :

                AlipayTradeAppPayModel appModel = new AlipayTradeAppPayModel();
                appModel.setOutTradeNo(request.getOutTradeNo());
                appModel.setProductCode("QUICK_MSECURITY_PAY");
                appModel.setTotalAmount(String.valueOf(f));
                appModel.setSubject(request.getBody());
                appModel.setGoodsType("1");

                AlipayTradeAppPayRequest appCallReq = new AlipayTradeAppPayRequest();
                appCallReq.setBizModel(appModel);
                appCallReq.setNotifyUrl(this.getNotifyUrl(payConfig));
                appCallReq.setReturnUrl(request.getReturnUrl());

                try {
                    result.addReq(JSON.toJSONString(appCallReq));
                    String form = AliPayApi.sdkExecute(appCallReq).getBody();
                    result.addResp(form);
                    Map<String, String> biz = new HashMap<String, String>();
                    biz.put("html", form);
                    result.setBiz(biz);
                    System.out.println(JSON.toJSONString(result));
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                } finally {
                    AliPayApiConfigKit.removeThreadLocalAppId();
                }

                return result;

            default:
                throw new IllegalStateException("Unexpected value: " + ptt.getTradeType());

        }


    }

    @Override
    public ThirdPayResp closeOrder(PayApiConfig payConfig, PayOrderCloseRequest request) {
        return null;
    }

    @Override
    public ThirdQueryOrderResp queryOrder(PayApiConfig payConfig, PayOrderQueryRequest request) {
        AliPayApiConfig aliPayApiConfig = this.getAliPayApiConfig(payConfig);
        AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(request.getOutTradeNo());

        ThirdQueryOrderResp result = new ThirdQueryOrderResp();
        try {

            result.addReq(JSON.toJSONString(model));
            AlipayTradeQueryResponse resp = AliPayApi.tradeQueryToResponse(model);
            result.addResp(resp.getBody());

            result.setOutTradeNo(resp.getOutTradeNo());
            if ("ACQ.TRADE_NOT_EXIST".equals(resp.getSubCode())) {
                result.setTradeState("ACQ.TRADE_NOT_EXIST");
                result.setState(WxPayStateConvertKit.convertAliPayState(result.getTradeState()));
            } else {
                result.setTradeState(resp.getTradeStatus());
                result.setState(WxPayStateConvertKit.convertAliPayState(result.getTradeState()));
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        } finally {
            AliPayApiConfigKit.removeThreadLocalAppId();
        }

        return result;
    }

}
